﻿
using Furion.LinqBuilder;
using Furion.Localization;
using ST.Torch.WebApi.Application.System.Dtos;
using ST.Torch.WebApi.Application.System.Services;
using ST.Torch.WebApi.Core.Entities.System;
using System.Data;
using System.Linq.Expressions;


namespace ST.Torch.WebApi.Application.System
{

    /// <summary>
    /// 系统服务接口
    /// </summary>
    [AppAuthorize]
    public class SYSRoleAppService : IDynamicApiController
	{
		private readonly SYSRoleService _SYSRoleService;
		private readonly SYSMenuService _SYSMenuService;
        private readonly IUIDService _UIDService;

        public SYSRoleAppService(SYSRoleService SYSRoleService, SYSMenuService sYSMenuService, IUIDService uIDService)
        {
            _SYSRoleService = SYSRoleService;
            _SYSMenuService = sYSMenuService;
            _UIDService = uIDService;
        }


        [HttpPost]
		public async Task<PagedList<SYSRoleListDto>> GetRolePagedList([FromForm] PageReq req)
		{
			Expression<Func<SYSRole, bool>> predicate = u => true;
            predicate=predicate.AndIf(!string.IsNullOrEmpty(req.key),u=>u.Name.Contains(req.key) || u.Name.Contains(req.key));
			
			var dataList= await _SYSRoleService.QueryPageAsync(predicate, req);
			PagedList<SYSRoleListDto> resultList = dataList.Adapt<PagedList<SYSRoleListDto>>();

			return resultList;
		}
        [HttpPost]
        public async Task<SYSRoleListDto> Single([FromForm] Guid Id)
        {
           
           var entity= await _SYSRoleService.SingleAsync(u=>u.Id==Id);
            SYSRoleListDto resultData = entity.Adapt<SYSRoleListDto>();
			return resultData;

        }
        [HttpPost]
        public async Task Insert([FromForm] SYSRoleDto model)
        {
            SYSRole entity = model.Adapt<SYSRole>();
            if (string.IsNullOrWhiteSpace(entity.RoleCode))
            {
                throw Oops.Oh($"{model.RoleCode} " + L.Text["角色标识不能为空"]);
            }
            else if ( await _SYSRoleService.AnyAsync(u => u.RoleCode == model.RoleCode))
            {
                throw Oops.Oh($"{model.RoleCode} " + L.Text["角色标识已存在"]);
            }
            await _SYSRoleService.InsertAsync(entity);
        }
		[HttpPost]
		public async Task Update([FromForm] SYSRoleListDto model)
		{
			
			var entity=await _SYSRoleService.SingleAsync(u => u.Id == model.Id);
			entity.Name=model.Name;
			
            if (string.IsNullOrWhiteSpace(entity.RoleCode))
            {
                throw Oops.Oh($"{model.RoleCode} " + L.Text["角色标识不能为空"]);
            }
            else if ( entity.RoleCode != model.RoleCode&& await _SYSRoleService.AnyAsync(u => u.RoleCode == model.RoleCode))
            {
                throw Oops.Oh($"{model.RoleCode} " + L.Text["角色标识已存在"]);
            }
            entity.RoleCode = model.RoleCode;

            await _SYSRoleService.UpdateAsync(entity);
		}
		[HttpPost]
		public async Task DeleteAsync([FromForm] Guid Id)
		{
			var entity = await _SYSRoleService.SingleAsync(u => u.Id == Id);
			await _SYSRoleService.DeleteAsync(entity,true);
		}

        [HttpPost]
        public async Task DeleteBatchAsync([FromForm] List<Guid> Ids)
        {
            var entitys = await _SYSRoleService.QueryAsync(u => Ids.Contains(u.Id));
            foreach (var entity in entitys)
            {
                await _SYSRoleService.DeleteAsync(entity, true);
            }
        }


        [HttpPost]
        public async Task InsertRoleMenu([FromForm] Guid RoleId, [FromForm] List<Guid> MenuIds)
        {
            var entity = await _SYSRoleService.SingleAsync(u => u.Id == RoleId,true,true, true);
            var menus = await _SYSMenuService.QueryAsync(u => MenuIds.Contains( u.Id));
            List<SYSMenu> DelData = new List<SYSMenu>();
            List<SYSMenu> AlreadyAddData = new List<SYSMenu>();
            foreach (var item in entity.Menus)
            {
                if (menus.Any(u => u.Id == item.Id))
                {
                    AlreadyAddData.Add(item);
                }
                else
                {
                    DelData.Add(item);
                }
            }
            foreach (var item in DelData)
            {
                entity.Menus.Remove(item);
            }
            foreach (var item in menus)
            {
                if (!AlreadyAddData.Any(u => u.Id == item.Id))
                {
                    entity.Menus.Add(item);// = new List<SYSMenu>();
                }
            }
            await _SYSRoleService.UpdateAsync(entity);
            foreach (var item in entity.Users)
            {
                await _UIDService.CleanCacheById(item.Id);
            }
           
            //await entity.UpdateAsync();
            return ;


        }

        [HttpPost]

        public async Task<dynamic> GetRoleMenu([FromForm] Guid Id)
		{
            var entity = await _SYSRoleService.QueryAsync(u => u.Id ==Id,true);
           var MenuIdss= entity.Select(u=>u.Menus.Select(u=>u.Id).ToList()).ToList();
            List<Guid> MenuIds = new List<Guid>();
            foreach (var menu in MenuIdss)
            {
                MenuIds.AddRange(menu);
            }
            var Data =await  GetSelectTreeMenu(MenuIds);
            return Data;


        }
        /// <summary>
        /// 获取权限下拉菜单树
        /// </summary>
        /// <returns></returns>
        [HttpGet, NonUnify]
        private async Task<List<SYSMenuTreeSelectListDto>> GetSelectTreeMenu(List<Guid> MenuIds)
        {
            Expression<Func<SYSMenu, bool>> expression = x => x.Type == MenuTypeEnum.Menu || x.Type == MenuTypeEnum.Page || x.Type == MenuTypeEnum.Button;
            var modules = await _SYSMenuService.QueryAsync(expression);

            

            List<SYSMenuTreeSelectListDto> MenuSecurities = new List<SYSMenuTreeSelectListDto>();
            MenuSecurities.AddRange(GetTreeSelectMenus(modules, new Guid(), MenuIds));
            return MenuSecurities;
            //return new
            //{
            //    status = new { code = 200, message = "ok" },
            //    data = MenuSecurities
            //};
            
        }

        /// <summary>
        /// 循环获取菜单树
        /// </summary>
        /// <param name="systemModules"></param>
        /// <param name="pId"></param>
        /// <returns></returns>
        private List<SYSMenuTreeListDto> GetTreeMenus(List<SYSMenu> systemModules, Guid? pId)
        {
            List<SYSMenuTreeListDto> MenuSecurities = new List<SYSMenuTreeListDto>();
            foreach (var menu in systemModules.FindAll(r => r.ParentId == pId))
            {
                if (menu.Type == MenuTypeEnum.Menu || menu.Type == MenuTypeEnum.Page)
                {
                    var menuSecurity = menu.Adapt<SYSMenuTreeListDto>();
                  
                    menuSecurity.children = GetTreeMenus(systemModules, menu.Id);
                    MenuSecurities.Add(menuSecurity);
                }
            }
            return MenuSecurities;
        }
        /// <summary>
        /// 循环获取菜单树
        /// </summary>
        /// <param name="systemModules"></param>
        /// <param name="pId"></param>
        /// <returns></returns>
        private List<SYSMenuTreeSelectListDto> GetTreeSelectMenus(List<SYSMenu> systemModules, Guid? pId,List<Guid> CheckMenus)
        {
            List<SYSMenuTreeSelectListDto> MenuSecurities = new List<SYSMenuTreeSelectListDto>();
            foreach (var menu in systemModules.FindAll(r => r.ParentId == pId))
            {
                if (menu.Type == MenuTypeEnum.Menu || menu.Type == MenuTypeEnum.Page || menu.Type == MenuTypeEnum.Button)
                {
                    var menuSecurity = menu.Adapt<SYSMenuTreeSelectListDto>();
                    menuSecurity.spread = true;
                    
                    menuSecurity.children = GetTreeSelectMenus(systemModules, menu.Id, CheckMenus);
                    if (CheckMenus.Any(u => u == menuSecurity.id)&& menuSecurity.children.Count()==0)
                    {
                        menuSecurity.@checked = true;
                    }
                    MenuSecurities.Add(menuSecurity);
                }
            }
            return MenuSecurities;
        }




    }

}
